import {ModalForm, ProFormText, ProFormTextArea} from '@ant-design/pro-components';
import {Form, message, Button, Select, Input, Space, Card, Divider, Alert} from 'antd';
import React, {useState, useEffect} from 'react';
import {createSwitchMeta, updateSwitchMeta} from '@/services/switch-meta/api';
import {useIntl, useRequest} from '@umijs/max';
import {PlusOutlined, DeleteOutlined, ExclamationCircleOutlined} from '@ant-design/icons';

export type CreateFormProps = {
  isCreate: boolean,
  values?: API.SwitchMetaItem;
  reload: () => void;
  trigger: React.ReactNode;
  readOnly?: boolean;
};


// JSON Schema 编辑器
// 使用的是json schema 第七版规范
// JSON Schema 校验函数
const validateJsonSchema = (schemaStr: string): { isValid: boolean; errors: string[] } => {
  if (!schemaStr.trim()) {
    return { isValid: false, errors: ['请输入 JSON Schema 内容'] };
  }

  try {
    const schema = JSON.parse(schemaStr);
    const errors: string[] = [];

    // 基本结构校验
    if (typeof schema !== 'object' || schema === null) {
      errors.push('Schema 必须是一个 JSON 对象');
    }

    // 检查 type 字段
    if (schema.type && !['string', 'number', 'integer', 'boolean', 'object', 'array', 'null'].includes(schema.type)) {
      errors.push(`不支持的数据类型: "${schema.type}"`);
    }

    // 检查 properties 字段
    if (schema.properties && typeof schema.properties !== 'object') {
      errors.push('properties 必须是一个对象');
    }

    // 检查 required 字段
    if (schema.required) {
      if (!Array.isArray(schema.required)) {
        errors.push('required 必须是一个数组');
      } else {
        // 检查 required 数组中的每个元素是否为字符串
        schema.required.forEach((item: any, index: number) => {
          if (typeof item !== 'string') {
            errors.push(`required[${index}] 必须是字符串`);
          }
        });

        // 如果有 properties 字段，检查 required 中的属性是否在 properties 中存在
        if (schema.properties && typeof schema.properties === 'object') {
          schema.required.forEach((requiredProp: string) => {
            if (typeof requiredProp === 'string' && !schema.properties.hasOwnProperty(requiredProp)) {
              errors.push(`必填字段 "${requiredProp}" 未在 properties 中定义`);
            }
          });
        } else if (schema.required.length > 0) {
          errors.push('定义了必填字段但缺少 properties');
        }
      }
    }

    // 检查 items 字段
    if (schema.items && typeof schema.items !== 'object') {
      errors.push('items 必须是一个对象');
    }

    // 检查数值约束
    if (schema.minimum !== undefined && typeof schema.minimum !== 'number') {
      errors.push('minimum 必须是数字');
    }
    if (schema.maximum !== undefined && typeof schema.maximum !== 'number') {
      errors.push('maximum 必须是数字');
    }
    if (schema.minLength !== undefined && (typeof schema.minLength !== 'number' || schema.minLength < 0)) {
      errors.push('minLength 必须是非负整数');
    }
    if (schema.maxLength !== undefined && (typeof schema.maxLength !== 'number' || schema.maxLength < 0)) {
      errors.push('maxLength 必须是非负整数');
    }

    // 检查数值范围关系
    if (schema.minimum !== undefined && schema.maximum !== undefined && schema.minimum > schema.maximum) {
      errors.push('最小值不能大于最大值');
    }

    if (schema.minLength !== undefined && schema.maxLength !== undefined && schema.minLength > schema.maxLength) {
      errors.push('最小长度不能大于最大长度');
    }

    // 检查类型相关的约束
    if (schema.type === 'object') {
      if (!schema.properties && schema.additionalProperties === false) {
        errors.push('对象类型需要定义 properties 或允许额外属性');
      }
    }

    if (schema.type === 'array') {
      if (!schema.items) {
        errors.push('数组类型需要定义 items 结构');
      }
    }

    // 检查字段适用性
    if (schema.type && schema.type !== 'string' && (schema.minLength !== undefined || schema.maxLength !== undefined || schema.pattern !== undefined)) {
      errors.push('长度和模式约束仅适用于字符串类型');
    }

    if (schema.type && !['number', 'integer'].includes(schema.type) && (schema.minimum !== undefined || schema.maximum !== undefined || schema.multipleOf !== undefined)) {
      errors.push('数值约束仅适用于数字类型');
    }

    if (schema.type && schema.type !== 'array' && (schema.minItems !== undefined || schema.maxItems !== undefined || schema.uniqueItems !== undefined)) {
      errors.push('数组约束仅适用于数组类型');
    }

    return { isValid: errors.length === 0, errors };
  } catch (e) {
    return { isValid: false, errors: ['⚠️ JSON 语法错误: ' + (e as Error).message] };
  }
};

const JsonSchemaEditor: React.FC<{
  value?: string;
  onChange?: (value: string) => void;
  readOnly?: boolean;
  validationErrors?: string[];
}> = ({ value, onChange, readOnly = false, validationErrors = [] }) => {
  const [schemaData, setSchemaData] = useState<any>({});

  const typeOptions = [
    { label: 'string (字符串)', value: 'string' },
    { label: 'number (数字)', value: 'number' },
    { label: 'integer (整数)', value: 'integer' },
    { label: 'boolean (布尔)', value: 'boolean' },
    { label: 'object (对象)', value: 'object' },
    { label: 'array (数组)', value: 'array' },
    { label: 'null (空值)', value: 'null' }
  ];

  const formatOptions = [
    { label: 'date-time (日期时间)', value: 'date-time' },
    { label: 'date (日期)', value: 'date' },
    { label: 'time (时间)', value: 'time' },
    { label: 'email (邮箱)', value: 'email' },
    { label: 'hostname (主机名)', value: 'hostname' },
    { label: 'ipv4 (IPv4地址)', value: 'ipv4' },
    { label: 'ipv6 (IPv6地址)', value: 'ipv6' },
    { label: 'uri (URI)', value: 'uri' },
    { label: 'uri-reference (URI引用)', value: 'uri-reference' },
    { label: 'iri (IRI格式)', value: 'iri' },
    { label: 'iri-reference (IRI引用)', value: 'iri-reference' },
    { label: 'uuid (UUID格式)', value: 'uuid' },
    { label: 'json-pointer (JSON指针)', value: 'json-pointer' },
    { label: 'relative-json-pointer (相对JSON指针)', value: 'relative-json-pointer' },
    { label: 'regex (正则表达式)', value: 'regex' }
  ];

  // 递归处理 JSON Schema，自动推断缺失的 type
  const processSchemaData = (data: any): any => {
    if (typeof data !== 'object' || data === null) {
      return data;
    }

    const processed = { ...data };

    if ((processed.format || processed.pattern) && !processed.type) {
      processed.type = 'string';
    }

    //以下内容需要递归处理
    ['anyOf', 'oneOf', 'allOf'].forEach(key => {
      if (Array.isArray(processed[key])) {
        processed[key] = processed[key].map((item: any) => processSchemaData(item));
      }
    });

    if (processed.items) {
      processed.items = processSchemaData(processed.items);
    }

    if (processed.properties && typeof processed.properties === 'object') {
      const newProperties: any = {};
      Object.keys(processed.properties).forEach(key => {
        newProperties[key] = processSchemaData(processed.properties[key]);
      });
      processed.properties = newProperties;
    }

    return processed;
  };

  useEffect(() => {
    if (value) {
      try {
        const parsed = JSON.parse(value);
        setSchemaData(parsed);
      } catch (e) {
        console.error('Invalid JSON Schema:', e);
      }
    }
  }, [value]);


  const updateSchema = (newData: any) => {
    if (readOnly) return;
    setSchemaData(newData);
    onChange?.(JSON.stringify(newData, null, 2));
  };

  // 根据type类型获取可用的属性
  const getAvailableProperties = (type: string) => {
    const commonProps = ['description', 'title', 'default', 'examples', 'anyOf', 'oneOf', 'allOf'];

    switch (type) {
      case 'string':
        return [...commonProps, 'minLength', 'maxLength', 'pattern', 'format', 'enum'];
      case 'number':
      case 'integer':
        return [...commonProps, 'minimum', 'maximum', 'multipleOf', 'enum'];
      case 'array':
        return [...commonProps, 'items', 'minItems', 'maxItems', 'uniqueItems'];
      case 'object':
        return [...commonProps, 'properties', 'required', 'additionalProperties', 'minProperties', 'maxProperties'];
      case 'boolean':
        return [...commonProps];
      default:
        return commonProps;
    }
  };

  const addProperty = (propName: string) => {
    const newData = { ...schemaData };

    switch (propName) {
      case 'properties':
        newData.properties = newData.properties || {};
        break;
      case 'required':
        newData.required = newData.required || [];
        break;
      case 'enum':
      case 'examples':
        newData[propName] = [];
        break;
      case 'anyOf':
      case 'oneOf':
      case 'allOf':
        newData[propName] = [{ type: 'string' }];
        break;
      case 'items':
        newData.items = { type: 'string' };
        break;
      case 'additionalProperties':
      case 'uniqueItems':
        newData[propName] = false;
        break;
      default:
        newData[propName] = '';
    }

    updateSchema(newData);
  };

  const removeProperty = (propName: string) => {
    const newData = { ...schemaData };
    delete newData[propName];
    updateSchema(newData);
  };

  // 每次更新schema的时候。同时校验schema && 更新schema的值
  const updateProperty = (propName: string, propValue: any) => {
    const newData = { ...schemaData };
    newData[propName] = propValue;

    if (propName === 'type') {
      const availableProps = getAvailableProperties(propValue);
      Object.keys(newData).forEach(key => {
        if (key !== 'type' && !availableProps.includes(key)) {
          delete newData[key];
        }
      });
    }

    updateSchema(newData);
  };

  const renderPropertyEditor = (propName: string, propValue: any) => {
    switch (propName) {
      case '$schema':
        return (
          <Input
            value={propValue}
            style={{ width: '100%' }}
            disabled={true}
            placeholder="JSON Schema 版本（第七版schema不可编辑）"
          />
        );

      case 'type':
        return (
          <Select
            value={propValue}
            style={{ width: '100%' }}
            options={typeOptions}
            onChange={(val) => updateProperty(propName, val)}
            placeholder="选择数据类型"
            disabled={readOnly}
          />
        );

      case 'format':
        return (
          <Select
            value={propValue}
            style={{ width: '100%' }}
            options={formatOptions}
            onChange={(val) => updateProperty(propName, val)}
            placeholder="选择格式"
            disabled={readOnly}
          />
        );

      case 'required':
        return (
          <Select
            mode="tags"
            value={propValue}
            style={{ width: '100%' }}
            placeholder="选择必需字段"
            onChange={(val) => updateProperty(propName, val)}
            disabled={readOnly}
          />
        );

      case 'enum':
      case 'examples':
        return (
          <Select
            mode="tags"
            value={propValue}
            style={{ width: '100%' }}
            placeholder={`输入${propName === 'enum' ? '枚举值' : '示例值'}`}
            onChange={(val) => updateProperty(propName, val)}
            disabled={readOnly}
          />
        );

      case 'items':
        return (
          <Card size="small" style={{ marginTop: '8px' }}>
            <div style={{ marginBottom: '8px', fontWeight: 'bold' }}>数组项类型:</div>
            <JsonSchemaEditor
              value={JSON.stringify(propValue, null, 2)}
              onChange={(val) => {
                try {
                  updateProperty(propName, JSON.parse(val));
                } catch (e) {
                }
              }}
              readOnly={readOnly}
            />
          </Card>
        );

      case 'anyOf':
      case 'oneOf':
      case 'allOf':
        return (
          <Card size="small" style={{ marginTop: '8px' }}>
            {Array.isArray(propValue) && propValue.map((item, index) => (
              <div key={index} style={{ marginBottom: '12px', padding: '8px', border: '1px solid #f0f0f0', borderRadius: '4px' }}>
                <Space style={{ width: '100%', justifyContent: 'space-between', marginBottom: '8px' }}>
                  <strong>选项 {index + 1}:</strong>
                  {!readOnly && (
                    <Button
                      type="text"
                      size="small"
                      icon={<DeleteOutlined />}
                      onClick={() => {
                        const newArray = [...propValue];
                        newArray.splice(index, 1);
                        updateProperty(propName, newArray);
                      }}
                      danger
                    />
                  )}
                </Space>
                <JsonSchemaEditor
                  value={JSON.stringify(item, null, 2)}
                  onChange={(val) => {
                    try {
                      const newArray = [...propValue];
                      newArray[index] = JSON.parse(val);
                      updateProperty(propName, newArray);
                    } catch (e) {
                    }
                  }}
                  readOnly={readOnly}
                />
              </div>
            ))}
            {!readOnly && (
              <Button
                type="dashed"
                icon={<PlusOutlined />}
                onClick={() => {
                  const newArray = Array.isArray(propValue) ? [...propValue] : [];
                  newArray.push({ type: 'string' });
                  updateProperty(propName, newArray);
                }}
                style={{ width: '100%' }}
              >
                添加选项
              </Button>
            )}
          </Card>
        );

      case 'properties':
        return (
          <Card size="small" style={{ marginTop: '8px' }}>
            <div style={{ marginBottom: '8px', fontWeight: 'bold' }}>对象属性:</div>
            {Object.keys(propValue || {}).map(key => {
              return (
                <div key={key} style={{ marginBottom: '12px', padding: '8px', border: '1px solid #f0f0f0', borderRadius: '4px' }}>
                  <Space style={{ width: '100%', justifyContent: 'space-between', marginBottom: '8px' }}>
                    <strong>
                      {key}:
                    </strong>
                    {!readOnly && (
                      <Button
                        type="text"
                        size="small"
                        icon={<DeleteOutlined />}
                        onClick={() => {
                          const newProps = { ...propValue };
                          delete newProps[key];
                          updateProperty(propName, newProps);
                        }}
                        danger
                      />
                    )}
                  </Space>
                  <JsonSchemaEditor
                    value={JSON.stringify(propValue[key], null, 2)}
                    onChange={(val) => {
                      try {
                        const newProps = { ...propValue };
                        newProps[key] = JSON.parse(val);
                        updateProperty(propName, newProps);
                      } catch (e) {
                      }
                    }}
                    readOnly={readOnly}
                  />
                </div>
              );
            })}
            <Input
              placeholder="输入新属性名，按回车添加"
              onPressEnter={(e) => {
                const target = e.target as HTMLInputElement;
                const newKey = target.value.trim();
                if (newKey) {
                  const newProps = { ...propValue };
                  newProps[newKey] = { type: 'string' };
                  updateProperty(propName, newProps);
                  target.value = '';
                }
              }}
              key={`property-input-${Object.keys(propValue || {}).length}`}
              disabled={readOnly}
            />
          </Card>
        );

      case 'minimum':
      case 'maximum':
      case 'minLength':
      case 'maxLength':
      case 'minItems':
      case 'maxItems':
      case 'minProperties':
      case 'maxProperties':
      case 'multipleOf':
        return (
          <Input
            type="number"
            value={propValue}
            onChange={(e) => updateProperty(propName, Number(e.target.value))}
            placeholder={`输入${propName}`}
            disabled={readOnly}
          />
        );

      case 'uniqueItems':
      case 'additionalProperties':
        return (
          <Select
            value={propValue}
            style={{ width: '100%' }}
            options={[
              { label: 'true', value: true },
              { label: 'false', value: false }
            ]}
            onChange={(val) => updateProperty(propName, val)}
            disabled={readOnly}
          />
        );

      default:
        return (
          <Input
            value={propValue}
            onChange={(e) => updateProperty(propName, e.target.value)}
            placeholder={`输入${propName}`}
            disabled={readOnly}
          />
        );
    }
  };

  const currentType = schemaData.type;
  const availableProps = currentType ? getAvailableProperties(currentType) : [];
  const unusedProps = availableProps.filter(prop => !schemaData.hasOwnProperty(prop));

  return (
    <div style={{ border: validationErrors.length > 0 ? '1px solid #ff4d4f' : '1px solid #d9d9d9', borderRadius: '6px', padding: '12px', maxHeight: '400px', overflowY: 'auto' }}>
      {validationErrors.length > 0 && (
        <div style={{
          background: 'linear-gradient(135deg, #fff2f0 0%, #ffebe6 100%)',
          border: '1px solid #ffccc7',
          borderRadius: '8px',
          padding: '16px',
          marginBottom: '16px',
          boxShadow: '0 2px 8px rgba(255, 77, 79, 0.1)'
        }}>
          <div style={{
            display: 'flex',
            alignItems: 'center',
            marginBottom: '12px',
            color: '#cf1322',
            fontWeight: 600,
            fontSize: '14px'
          }}>
            <ExclamationCircleOutlined style={{ marginRight: '8px', fontSize: '16px' }} />
            Schema 校验失败
          </div>
          <div style={{ fontSize: '13px', lineHeight: '1.6' }}>
            {validationErrors.map((error, index) => (
              <div
                key={index}
                style={{
                  display: 'flex',
                  alignItems: 'flex-start',
                  marginBottom: index < validationErrors.length - 1 ? '8px' : '0',
                  color: '#8c1f1f'
                }}
              >
                <span style={{
                  display: 'inline-block',
                  width: '6px',
                  height: '6px',
                  borderRadius: '50%',
                  backgroundColor: '#ff4d4f',
                  marginTop: '6px',
                  marginRight: '10px',
                  flexShrink: 0
                }} />
                <span>{error}</span>
              </div>
            ))}
          </div>
        </div>
      )}
      <Space direction="vertical" style={{ width: '100%' }}>
        <div>
          <strong>type:</strong>
          {renderPropertyEditor('type', schemaData.type)}
        </div>

        {Object.keys(schemaData).filter(key => key !== 'type').map(propName => {
          return (
            <div key={propName}>
              <Space style={{ width: '100%', justifyContent: 'space-between', marginBottom: '4px' }}>
                <strong>
                  {propName}:
                </strong>
                {propName !== '$schema' && !readOnly && (
                  <Button
                    type="text"
                    size="small"
                    icon={<DeleteOutlined />}
                    onClick={() => removeProperty(propName)}
                    danger
                  />
                )}
              </Space>
              {renderPropertyEditor(propName, schemaData[propName])}
            </div>
          );
        })}

        {unusedProps.length > 0 && !readOnly && (
          <Select
            placeholder="选择要添加的属性"
            style={{ width: '100%' }}
            onSelect={(propName: string) => addProperty(propName)}
            options={unusedProps.map(prop => ({
              label: prop,
              value: prop
            }))}
          />
        )}
      </Space>
    </div>
  );
};

const CreateUpdateForm: React.FC<CreateFormProps> = (props) => {
  const {values, trigger, isCreate, readOnly = false} = props;
  const intl = useIntl();
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [form] = Form.useForm();
  const [jsonSchemaValue, setJsonSchemaValue] = useState<string>('');
  const [schemaValidationErrors, setSchemaValidationErrors] = useState<string[]>([]);

  const [messageApi, contextHolder] = message.useMessage();

  useEffect(() => {
    if (isModalOpen) {
      if (values?.jsonSchema) {
        setJsonSchemaValue(values.jsonSchema);
      } else {
        setJsonSchemaValue('');
      }
      setSchemaValidationErrors([]);
    }
  }, [values, isModalOpen]);

  const {run, loading} = useRequest(
    (params: Partial<API.SwitchMetaItem>) => {
      return isCreate ? createSwitchMeta(params) : updateSwitchMeta(params);
    },
    {
      manual: true,
      onSuccess: () => {
        console.log(isCreate ? '创建成功' : '更新成功')
        messageApi.success(isCreate ? '创建成功' : '更新成功');
        setIsModalOpen(false);
        props.reload();
      },
      onError: () => {
        console.log(isCreate ? '创建失败，请重试' : '更新失败，请重试')
        messageApi.error(isCreate ? '创建失败，请重试' : '更新失败，请重试');
        setIsModalOpen(false);
      },
    },
  );

  const renderTrigger = () => {
    return <span onClick={() => setIsModalOpen(true)}>{trigger}</span>;
  };

  return (
    <>
      {contextHolder}
      {renderTrigger()}
      <ModalForm
        form={form}
        width={900}
        style={{
          paddingTop: '10px',
          marginLeft: "20px"
        }}
        labelCol={{flex: "0 0 25%"}}
        wrapperCol={{flex: "0 0 75%"}}
        title={isCreate ? intl.formatMessage({
          id: 'pages.switch-meta.searchTable.create',
          defaultMessage: '新建开关元信息',
        }) : readOnly ? intl.formatMessage({
          id: 'pages.switch-meta.searchTable.view',
          defaultMessage: '查看开关元信息',
        }) : intl.formatMessage({
          id: 'pages.switch-meta.searchTable.editChild',
          defaultMessage: '编辑开关元信息',
        })}
        open={isModalOpen}
        onOpenChange={setIsModalOpen}
        initialValues={values}
        submitter={readOnly ? false : {
          searchConfig: {
            resetText: '重置',
            submitText: '提交',
          },
          submitButtonProps: {
            type: 'primary',
            style: {
              marginLeft: "10px"
            },
            loading: loading,
          },
          resetButtonProps: {
            onClick: () => {
              // 重置应该清空当前表单数据
              form.resetFields();
              setJsonSchemaValue('');
              setSchemaValidationErrors([]);
            },
          },
        }}
        modalProps={{
          styles: {
            header: {
              paddingTop: '10px',
              paddingLeft: '10px'
            },
          },
          destroyOnClose: true
        }}
        onFinish={readOnly ? undefined : async (formValues) => {
          // 校验 JSON Schema
          const validation = validateJsonSchema(jsonSchemaValue);
          if (!validation.isValid) {
            setSchemaValidationErrors(validation.errors);
            return false;
          }

          // 清空校验错误
          setSchemaValidationErrors([]);

          const params = {...values, ...formValues, jsonSchema: jsonSchemaValue};
          await run(params);
        }}
      >
        <ProFormText
          name="factor"
          label={
            <>
              因子
              <span style={{color: '#999', fontSize: '12px', marginLeft: '8px'}}>
                (创建后不可修改)
                </span>
            </>
          }
          formItemProps={{
            style: {
              marginTop: "15px",
            },
            labelCol: {
              style: {
                paddingBottom: "10px",
              }
            },
          }}
          fieldProps={{
            style: {
              width: "95%"
            },
            disabled: !isCreate || readOnly
          }}

          rules={[{required: true, message: '请输入因子名称'}]}
        />
        <ProFormText
          name="alias"
          label={"因子别名"}
          formItemProps={{
            style: {
              marginTop: "15px",
            },
            labelCol: {
              style: {
                paddingBottom: "10px",
              }
            },
          }}
          fieldProps={{
            style: {
              width: "95%"
            },
            disabled: !isCreate || readOnly
          }}

          rules={[{required: true, message: '请输入因子别名'}]}
        />
        <ProFormTextArea
          name="description"
          label="因子描述"
          formItemProps={{
            style: {
              marginTop: "20px",
              marginBottom: "60px"
            },
            labelCol: {
              style: {
                paddingBottom: "10px",
              }
            },
          }}
          fieldProps={{
            style: {
              width: "95%"
            },
            disabled: readOnly
          }}
          rules={[{required: true, message: '请介绍一下这个因子'}]}
        />

        <Form.Item
          label="JSON Schema"
          style={{
            marginTop: "20px",
            marginBottom: "60px"
          }}
          labelCol={{
            style: {
              paddingBottom: "10px",
            }
          }}
        >
          <JsonSchemaEditor
            value={jsonSchemaValue}
            onChange={readOnly ? undefined : (value) => {
              setJsonSchemaValue(value);
              // 实时校验
              if (value.trim()) {
                const validation = validateJsonSchema(value);
                setSchemaValidationErrors(validation.errors);
              } else {
                setSchemaValidationErrors([]);
              }
            }}
            readOnly={readOnly}
            validationErrors={schemaValidationErrors}
          />
        </Form.Item>
      </ModalForm>
    </>
  );
};

export default CreateUpdateForm;
